#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <memory.h>

#include "FTP_Command.h"
#include "../sock_lib/sock_lib.h"

int FTP_USER(SOCKET socket, char *username, int usernamelength)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(usernamelength + 8);

	memcpy(buf, USER, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;
	memcpy(buf, username, usernamelength);
	buf += usernamelength;
	memcpy(buf, "\r\n", 2);
	buf += 2;
	
	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(USER).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_PASS(SOCKET socket, char *password, int passwordlength)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(passwordlength + 8);

	memcpy(buf, PASS, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;
	memcpy(buf, password, passwordlength);
	buf += passwordlength;
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);

	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(PASS).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_CWD(SOCKET socket, char *path, int pathlength)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(pathlength + 7);

	memcpy(buf, CWD, 3);
	buf += 3;
	memcpy(buf, " ", 1);
	buf += 1;
	memcpy(buf, path, pathlength);
	buf += pathlength;
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(CWD).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_PORT(SOCKET socket, char *port, int portlength)
{
	int length;
	char *buf, *point, *i;
	char name[255];
	struct hostent *hostinfo;
	char *ip, *port1_c, *port2_c;
	int port_int, port1, port2;

	point = buf = malloc(30);
	port1_c = malloc(4);
	port2_c = malloc(4);

	memcpy(buf, PORT, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;

	if (gethostname(name, sizeof(name)) == 0) 
	{
		if ((hostinfo = gethostbyname(name)) != NULL)
			ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list); 
	}

	if (ip != NULL)
	{
		i = ip;
		while (*i != '\0')
		{
			if (*i == '.') *i = ',';
			++i;
		}
	}

	memcpy(buf, ip, strlen(ip));
	buf += strlen(ip);

	port_int = atoi(port);
	port1 = port_int / 256;
	port2 = port_int % 256;
	_itoa_s(port1, port1_c, 5, 10);
	_itoa_s(port2, port2_c, 5, 10);

	memcpy(buf, ",", 1);
	buf += 1;
	memcpy(buf, port1_c, strlen(port1_c));
	buf += strlen(port1_c);
	memcpy(buf, ",", 1);
	buf += 1;
	memcpy(buf, port2_c, strlen(port2_c));
	buf += strlen(port2_c);
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);

	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(PORT).");
		free(hostinfo);
		free(ip);
		free(port1_c);
		free(port2_c);
		free(point);
		return -1;
	}
	free(port1_c);
	free(port2_c);
	free(point);
	return 0;
}

int FTP_RETR(SOCKET socket, char *filename, int filenamelength)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(filenamelength + 8);

	memcpy(buf, RETR, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;
	memcpy(buf, filename, filenamelength);
	buf += filenamelength;
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(RETR).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_TYPE(SOCKET socket, char type)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(9);

	memcpy(buf, TYPE, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;
	*buf = type;
	buf += 1;
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(TYPE).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_REST(SOCKET socket, long start_position)
{
	int length;
	char *buf, *point, *temp;
	
	point = buf = malloc(21);
	temp = malloc(30);

	_ltoa_s(start_position, temp, 30, 10);

	memcpy(buf, REST, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;
	memcpy(buf, temp, strlen(temp));
	buf += strlen(temp);
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(REST).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_LIST(SOCKET socket, char *filename, int filenamelength)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(filenamelength + 8);

	memcpy(buf, LIST, 4);
	buf += 4;
	memcpy(buf, " ", 1);
	buf += 1;
	memcpy(buf, filename, filenamelength);
	buf += filenamelength;
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(LIST).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}

int FTP_PASV(SOCKET socket)
{
	int length;
	char *buf, *point;
	
	point = buf = malloc(7);

	memcpy(buf, PASV, 4);
	buf += 4;
	memcpy(buf, "\r\n", 2);
	buf += 2;

	length = (int)(buf - point);
	
	if (Send(socket, point, length) != length)
	{
		printf("Error at Send(PASV).");
		free(point);
		return -1;
	}
	free(point);
	return 0;
}